home *** CD-ROM | disk | FTP | other *** search
/ PC World 2006 November / PCWorld_2006-11_cd.bin / domacnost a kancelar / findgraph / fgraph.exe / {app} / ApprSource / poli_2.cpp < prev    next >
C/C++ Source or Header  |  2003-04-10  |  9KB  |  359 lines

  1. /******************************************************************************
  2.  * Plug-In DLL Example and Template
  3.  * for use with C/C++
  4.  *
  5.  * Compile DLL with any name.
  6.  * Place it in  the program FindGraph subfolder "Appr".
  7.  * Next functions must be exported:
  8.  *        MaxOfFactors
  9.  *        Prepare
  10.  *        CalcInPoint
  11.  *        FunctionTitle
  12.  *        FunctionName 
  13.  *        FunctionString
  14.  *        ParamInfo
  15.  * 
  16.  * To test DLL, restart FundGraph, 
  17.  * start The Wizard of approximation,
  18.  * on step 2 select 'User defined function'.
  19.  * If all right, on step 3 your function will appear in list.
  20.  * 
  21.  ******************************************************************************/
  22.  
  23.  
  24. #include <windows.h>
  25. #include <tchar.h>
  26. #include <math.h>
  27. #include "poli_n.h"
  28.  
  29.  
  30. #include <stdio.h>
  31.  
  32.  
  33. // 
  34. #pragma comment(linker,"/MERGE:.rdata=.text")
  35. #pragma comment(linker,"/FILEALIGN:512 /SECTION:.text,EWRX /IGNORE:4078")
  36.  
  37. //////////////////////////////////////////////////////////////////////////////////
  38.  
  39.  
  40. HINSTANCE g_hInstance=NULL;
  41. BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
  42. {
  43.     switch (ul_reason_for_call)
  44.     {
  45.         case DLL_PROCESS_ATTACH:
  46.              g_hInstance = (HINSTANCE )hModule;
  47.              break;
  48.         case DLL_PROCESS_DETACH:
  49.              break;
  50.     }
  51.      return TRUE;
  52. }
  53.  
  54.  
  55.  
  56.  
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////
  58. #define N_FACTORS 10 
  59. #define aa(i,j) pfs[i*nn+j]
  60.  
  61. // 2 linear equations
  62. // Input
  63. // pfs = matrix [2,3]
  64. // Output
  65. // pfu - vector [2]
  66. //
  67. void CalcEquGauss2(double *pfs, double *pfu)
  68. {
  69.   int    n = 1,
  70.         nn = n+2;
  71.  
  72.     
  73.     double d = aa(0,0) * aa(1,1) - aa(0,1)*aa(1,0);
  74.     if (d == 0.) 
  75.     {
  76.         pfu[1] = 0.;
  77.         pfu[0] = (aa(0,0) != 0.) ? aa(0,2) / aa(0,0) : 0.;
  78.     }
  79.     else
  80.     {
  81.         pfu[0] = (aa(1,1)*aa(0,2) - aa(0,1)*aa(1,2)) / d;
  82.         pfu[1] = (aa(0,0)*aa(1,2) - aa(1,0)*aa(0,2)) / d;
  83.     }
  84. }
  85.  
  86.  
  87.  
  88. // Error of calculus
  89. //
  90. double CalcError(double *pfU, double *pfV, int nPoints, 
  91.                  double *pfFactors, int nFactors)
  92. {
  93.     if (nPoints  <= 0)
  94.         return 0.;
  95.     double fError = 0.;
  96.     for (int id=0; id < nPoints; id++ )
  97.     {
  98.         double u = pfU[id],
  99.                v = pfV[id],
  100.                v1= CalcInPoint(u, pfFactors, nFactors);
  101.         fError += (v1-v)*(v1-v);
  102.     }
  103.     fError = sqrt(fError/nPoints);
  104.     return fError;
  105. }
  106.  
  107. ////////////////////////////////////////////////////////////////////////////////////////////////////
  108. //
  109. // Return the number of factors (see function 'Prepare')
  110. // use to memory allocate for pfFactors
  111. //
  112.  
  113. //extern "C" bool __declspec( dllexport ) __stdcall TransFromDisk(char *Base, char *Disk);
  114.  
  115.  
  116. int __declspec(dllexport) __stdcall MaxOfFactors()
  117. {
  118.     return N_FACTORS;
  119. }
  120.  
  121.  
  122. //
  123. // Prepare approximation function V(U) = Function(U)
  124. //     V(U) = V0 + (U-U0)*(A0 + A1*U)
  125. // Input:
  126. // Array of points (U,V)
  127. //        fMinU, fMaxU - limits of U 
  128. //        fMinV, fMaxV - limits of V 
  129. //        pfU, pfV - array of nPoints points (U,V)
  130. //        pfW         - weight of point
  131. //      nPoints     - number of points in array 
  132. // Parameters:
  133. //        pfParams - array of parameters
  134. //        U0 = pfParams[0]    
  135. //        V0 = pfParams[1]    
  136. //      nParams  - number of parameters in array 
  137. //
  138. // Output:
  139. // Array of factors is calculated.
  140. // This factors will be used in function CalcInPoint(U, pfFactors)
  141. //        pfFactors - array of factors, defined by user
  142. //        Notes: pfFactors[*pnFactors-1] = Error of calculus
  143. //      nFactors:
  144. //            Input  - maximum possible number of factors in array 
  145. //
  146. // return: number of factors if success, else error code
  147. //
  148. int __declspec(dllexport) __stdcall Prepare (double fMinU, double fMaxU, double fMinV, double fMaxV,
  149.                double *pfU, double *pfV, double *pfW, int nPoints, 
  150.                double *pfParams , int nParams ,
  151.                double *pfFactors, int nFactors)
  152. {
  153.     int nResult = 0;
  154.     if (nPoints < 2) // not enough points
  155.         return -1;
  156.  
  157.     if (nFactors < N_FACTORS) // not enough memory for result
  158.         return -2;
  159.  
  160.  
  161.     int    
  162.            nAppr = 1,
  163.            nn = nAppr + 2,
  164.            ns =(nAppr+1)*(nn+1);
  165.  
  166.     double fU0 = pfParams[0],
  167.            fV0 = pfParams[1];
  168.  
  169.     double 
  170.            *pfs,
  171.            *pfu;
  172.     // use: aa(i,j) == pfs[i*nn+j]
  173.  
  174.  
  175.     pfu = new double[nAppr+1];// calced coeff 
  176.     pfs = new double[ns];
  177.     memset(pfs, 0, ns*sizeof(double));
  178.  
  179.  
  180.         int  nSum = 0; // point with U>0, V>0
  181.         for (int id=0; id < nPoints; id++ )
  182.         {
  183.             if (pfU[id] == fU0) continue;
  184.             double u =  pfU[id],
  185.                    v = (pfV[id] - fV0) / (pfU[id] - fU0);
  186.                 aa(0,0) +=  1*1;
  187.                 aa(0,1) +=  1*u;
  188.                 aa(0,2) +=  1*v;
  189.                 aa(1,0) +=  u*1;
  190.                 aa(1,1) +=  u*u;
  191.                 aa(1,2) +=  u*v;
  192.  
  193.                 nSum++;
  194.         }
  195.         if (nSum >= 2)
  196.         {
  197.             CalcEquGauss2(pfs, pfu);
  198.             nResult         = N_FACTORS;
  199.             
  200.             pfFactors[0] = nSum;
  201.             pfFactors[1] = fMinU; pfFactors[2] = fMaxU; // Unused now - reserved
  202.             pfFactors[3] = fMinV; pfFactors[4] = fMaxV; // Unused now - reserved
  203.             pfFactors[4] = 0; // Unused now - reserved
  204.             pfFactors[5] = fU0;
  205.             pfFactors[6] = fV0;
  206.             pfFactors[7] = pfu[0]; // A0
  207.             pfFactors[8] = pfu[1]; // A1
  208.  
  209.             pfFactors[N_FACTORS-1] = CalcError(pfU, pfV, nPoints, pfFactors, nFactors); 
  210.         }
  211.  
  212.  
  213.  
  214.     delete [] pfu;
  215.     delete [] pfs;
  216.     return nResult;
  217. }
  218.  
  219. // Calculate value V = Function(fU)
  220. // Input:
  221. //        fU
  222. //        pfFactors - array of factors, prepared in finction Prepare()
  223. //      pnFactors: - number of factors in array 
  224. //
  225. // return: value calculated
  226. //
  227. double __declspec(dllexport) __stdcall CalcInPoint(double fU, 
  228.                                          double *pfFactors, int nFactors)
  229. {
  230.     double fV = 0.;
  231.     if (nFactors < N_FACTORS)
  232.         return  0.;
  233.     double 
  234.             U0 = pfFactors[5],
  235.             V0 = pfFactors[6],
  236.             A0 = pfFactors[7],
  237.             A1 = pfFactors[8],
  238.             U  = fU;
  239.     fV = V0 + (U-U0)*(A0 + A1*U);
  240.  
  241.     return fV;
  242. }
  243.  
  244.  
  245. // Fill information string with name of approximation method
  246. // It is used in FindGraph <Master of approximations page 2><list of user defined functions>
  247. // for example - "User's poli_n"
  248. // Input:
  249. //        pstr - buffer TCHAR
  250. //      nMaxLength - maximum buffer length
  251. //
  252. // Output:
  253. //        pstr - name of approximation method
  254. //
  255. // return: string length if success, else -1
  256. //
  257. int __declspec(dllexport) __stdcall FunctionTitle(LPTSTR pstr, int nMaxLength) 
  258. {
  259.     if (pstr==0)
  260.         return -1;
  261.     lstrcpyn(pstr, TEXT(" y = V0 + (x-U0)*(A0 + A1*x) (see sample in \'ApprSource\')"), nMaxLength);
  262.     return lstrlen(pstr);
  263. }
  264.  
  265.  
  266.  
  267. // Fill information string with name of approximation function
  268. // for example - "V(U) = V0 + Exp(a*(U-U0))*Pow((U-U0), b)"
  269. // It is used in FindGraph <Master of approximations page 3><Function description>
  270. // Input:
  271. //        pstr - buffer TCHAR
  272. //      nMaxLength - maximum buffer length
  273. //
  274. // Output:
  275. //        pstr - name of approximation function
  276. //
  277. // return: string length if success, else -1
  278. //
  279. int __declspec(dllexport) __stdcall FunctionName(LPTSTR pstr, int nMaxLength) 
  280. {
  281.     if (pstr==0)
  282.         return -1;
  283.     lstrcpyn(pstr, TEXT("f(U) = V0 + (U-U0)*(A0 + A1*U)"), nMaxLength);
  284.     return lstrlen(pstr);
  285. }
  286.  
  287.  
  288.  
  289. // Fill information string with formula of calculated function f(U) = Formula()
  290. // It is used in FindGraph <Master of approximations pages 4 and 5>
  291. // Input:
  292. //        pstr - buffer TCHAR
  293. //      nMaxLength - maximum buffer length
  294. //        pfFactors - array of factors, prepared in finction Prepare()
  295. //      pnFactors: - number of factors in array 
  296. //
  297. // Output:
  298. // pstr - string of calculated function f(U)
  299. //
  300. // return: string length if success, else -1
  301. //
  302. int __declspec(dllexport) __stdcall FunctionString(double *pfFactors, int nFactors,
  303.                                          LPTSTR pstr, int nMaxLength) 
  304. {
  305.     if (pstr==0)
  306.         return -1;
  307.     if (nFactors < N_FACTORS)
  308.         return -2;
  309.  
  310.     TCHAR  sz[256];
  311.     double 
  312.             U0 = pfFactors[5],
  313.             V0 = pfFactors[6],
  314.             A0 = pfFactors[7],
  315.             A1 = pfFactors[8];
  316.  
  317.     sprintf(sz, TEXT("f(U) = %4.4g + (U-%4.4g)*(%4.4g + %4.4g*U)"), V0, U0, A0, A1);
  318.     lstrcpyn(pstr, sz, nMaxLength);
  319.     return lstrlen(pstr);
  320. }
  321.  
  322.  
  323.  
  324. // Fill information string with name of parameter and it's default value
  325. // It is used in FindGraph <Master of approximations page 3>
  326. // Input:
  327. //      nParam - number of edit box in page 3
  328. //                 1, 2, 3, 4
  329. //               see list of pfParams in function 'Prepare'
  330. //        pstr - buffer TCHAR
  331. //      nMaxLength - maximum buffer length
  332. //
  333. // Output:
  334. //        pstr - name of parameter[nParam]
  335. //      pfDefault - default value of parameter[nParam]
  336. //
  337. // return: string length if success, else -1
  338. //
  339. int __declspec(dllexport) __stdcall ParamInfo(int nParam, LPTSTR pstr, int nMaxLength, double *pfDefault) 
  340. {
  341.     if (pstr==0)
  342.         return -1;
  343.     switch (nParam)
  344.     {
  345.         case 1: 
  346.             lstrcpyn(pstr, TEXT("U0"), nMaxLength);
  347.             if (pfDefault != NULL)
  348.                *pfDefault = 0.;
  349.             break;
  350.         case 2: 
  351.             lstrcpyn(pstr, TEXT("V0"), nMaxLength);
  352.             if (pfDefault != NULL)
  353.                *pfDefault = 0.;
  354.             break;
  355.         default: return -1;
  356.     }
  357.     return lstrlen(pstr);
  358. }
  359.